package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.WemediaContans;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.threadlocal.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 查询文章列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //1.非空判断
        dto.checkParam();
        //2.分页查询
        IPage<WmNews> page=new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper= Wrappers.lambdaQuery();
        //2.1 根据状态查询
        if(dto.getStatus()!=null){
            queryWrapper.eq(WmNews::getStatus,dto.getStatus());
        }

        //2.2 根据关键字查询
        if(!StringUtils.isEmpty(dto.getKeyword())){
            queryWrapper.like(WmNews::getTitle,dto.getKeyword());
        }

        //2.3 根据频道id查询
        if(dto.getChannelId()!=null){
            queryWrapper.eq(WmNews::getChannelId,dto.getChannelId());
        }

        //2.4 根据开始和结束时间查询
        if(dto.getBeginPubdate()!=null && dto.getEndPubdate()!=null){
            queryWrapper.between(WmNews::getPublishTime,dto.getBeginPubdate(),dto.getEndPubdate());
        }

        //2.5 根据登录用户id查询
        queryWrapper.eq(WmNews::getUserId, WmThreadLocalUtil.getUser().getId());
        queryWrapper.orderByDesc(WmNews::getCreatedTime);

        page=super.page(page,queryWrapper);

        //3.返回数据结果
        ResponseResult result=new PageResponseResult(dto.getPage(),dto.getSize(), (int) page.getTotal());
        result.setData(page.getRecords());
        return result;
    }

    /**
     * 保存-修改-提交草稿为一体的方法
     *  主方法
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveNews(WmNewsDto dto,Short isSubmit) {
        //TODO
        //保存、修改草稿
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        //如果封面图片选择是自动的话，则从内容中的图片作为封面图片
        if (WemediaContans.WM_NEWS_TYPE_AUTO.equals(dto.getType())){
           wmNews.setType(null);
        }
        //自动匹配规则1：内容中无图 ，不用选择封面图片，则设置为封面是无图结构
        if (dto.getImages() == null){
            wmNews.setType((short) 0);
        }
        //自动匹配规则2：内容中的图片数量大于等于1，小于3，选择1张内容图片作为封面内图片，且设置封面布局方式为单图布局
        if (dto.getImages() != null && dto.getImages().size() >= 1 && dto.getImages().size() < 3){
            wmNews.setType((short) 1);
            wmNews.setImages(dto.getImages().toString());
        }
        //自动匹配规则3：内容中的图片数量大于等于3，选择3张内容图片作为封面图片，且设置封面布局方式为多图布局
        if (dto.getImages() != null && dto.getImages().size() > 3){
            wmNews.setType((short) 3);
            wmNews.setImages(dto.getImages().toString());
        }
        saveWmNews(wmNews,isSubmit);
        //关联文章与素材的关系
        String content = dto.getContent();
        List<Map> list = JSON.parseArray(content, Map.class);
        List<String> materials = getImages(list);
        //关联内容中的图片与素材的关系
        if (isSubmit == WmNews.Status.SUBMIT.getCode() && materials.size() != 0){
            ResponseResult responseResult = saveContentMaterial(materials,wmNews.getId());
            if (responseResult != null){
                return responseResult;
            }
        }
        //联封面中的图片与素材的关系,设置wm_news的type,自动
        if (isSubmit == WmNews.Status.SUBMIT.getCode()) {
            ResponseResult responseResult = saveRelativeInfoForCover(dto, materials, wmNews);
            if (responseResult != null) {
                return responseResult;
            }
        }
        //6.返回数据
        return ResponseResult.okResult("发布文章完成");
    }

    /**
     * 设置封面图片与素材的关系
     */
    private ResponseResult saveRelativeInfoForCover(WmNewsDto dto, List<String> materials, WmNews wmNews) {
        List<String> images = dto.getImages();
            //自动匹配封面
            if (dto.getType().equals(WemediaContans.WM_NEWS_TYPE_AUTO)) {
            //内容中的图片数量大于等于1同时小于3，设置为单图
            if (materials.size() >= 1 && materials.size() < 3) {
                wmNews.setType(WemediaContans.WM_NEWS_SINGLE_IMAGE);
                images = materials.stream().limit(1).collect(Collectors.toList());
            } else if (materials.size() > 3) {
                //如果内容中的图片大于3 则设置为多图
                wmNews.setType(WemediaContans.WM_NEWS_MANY_IMAGE);
                images = materials.stream().limit(3).collect(Collectors.toList());
            } else {
                //内容中没有图片，则是无图
                wmNews.setType(WemediaContans.WM_NEWS_NONE_IMAGE);
            }
            //修改文章信息
            if (images != null && images.size() > 0) {
                wmNews.setImages(images.toString());

            }
            updateById(wmNews);
        }
        //保存封面图片与素材的关系
        if (images != null && images.size() > 0) {
            ResponseResult responseResult = saveRelativeInfoForImage(images, wmNews.getId());
            if (responseResult != null) {
                return responseResult;
            }
        }
        return null;
    }
    /**
     *保存素材与图片的关系
     */
    private ResponseResult saveRelativeInfoForImage(List<String> images, Integer newsId) {
        List<String> materials = new ArrayList<>();
        for (String image : images) {
            materials.add(image);
        }

        return saveMaterial(materials,newsId,WemediaContans.WM_COVER_REFERENCE);
    }



    /**
     * 保存素材和文章内容的关系
     */
    public ResponseResult saveContentMaterial(List<String> materials,Integer newsId){
        return saveMaterial(materials, newsId, WemediaContans.WM_CONTENT_REFERENCE);
    }

    /**
     * 保存关系
     */
    private ResponseResult saveMaterial(List<String> materials, Integer newsId, Short type) {
        //1.获取数据库中的素材信息
        LambdaQueryWrapper<WmMaterial> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(WmMaterial::getUrl, materials);
        lambdaQueryWrapper.eq(WmMaterial::getUserId, WmThreadLocalUtil.getUser().getId());
        List<WmMaterial> dbMaterials = wmMaterialMapper.selectList(lambdaQueryWrapper);
        //2.通过图片的路径获取素材的id
        List<String> materialsIds = new ArrayList<>();
        if (dbMaterials != null && dbMaterials.size() > 0) {
            //<kdjfksdjkfljdsf.jps,2>
            Map<String, Integer> uriIdMap = dbMaterials.stream().collect(Collectors.toMap(WmMaterial::getUrl, WmMaterial::getId));
            for (String val : materials) {
                String materialId = String.valueOf(uriIdMap.get(val));
                //没找到
                if ("null".equals(materialId)) {
                    return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "应用图片失效");
                }
                //找到了
                materialsIds.add(materialId);
            }
        }

        //3.批量保存数据
        wmNewsMaterialMapper.saveRelations(materialsIds, newsId, type);
        return null;
    }

    /**
     * 获取图片信息
     */
    public List<String> getImages(List<Map> list){
        List<String> materials = new ArrayList<>();
        for (Map map : list) {
            if (map.get("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)){
                String imageUrl = (String) map.get("value");
                materials.add(imageUrl);
            }
        }
       return materials;
    }


    /**
     * 保存或修改文章
     */
    private void saveWmNews(WmNews wmNews, Short isSubmit) {
        wmNews.setStatus(isSubmit);
        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        wmNews.setEnable((short) 1);
        if (wmNews.getId() == null) {
            save(wmNews);
        } else {
            //如果是修改，则先删除素材与文章的关系
            LambdaQueryWrapper<WmNewsMaterial> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(WmNewsMaterial::getNewsId, wmNews.getId());
            wmNewsMaterialMapper.delete(queryWrapper);
            updateById(wmNews);
        }
    }

    /**
     * 文章上下架
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
       //TODO
        return ResponseResult.okResult("文章上下架完成");
    }
}
